import axios from 'axios'
import store from '../store/store.js';
// var instance = axios.create()
// 全局配置
// 超时时间10s
axios.defaults.timeout = 10000
const reqQueue = {}
// 请求拦截器
axios.interceptors.request.use(
    function (config) {
        // 在发送请求之前做些什么
        config.headers['Authorization'] = store.getState().userInfo.token
        config = cancelReq(config)
        return config
    },
    function (error) {
        // 对请求错误做些什么
        return Promise.reject(error)
    }
)
// 相应拦截器
// 添加响应拦截器
axios.interceptors.response.use(
    function (response) {
        // 对响应数据做点什么
        return response
    },
    function (error) {
        // 对响应错误做点什么
        return Promise.reject(error)
    }
)

// 取消请求
function cancelReq(config) {
    if (config['cancel']) {
        const CancelToken = axios.CancelToken
        // const source = CancelToken.source();
        const key = `${config.method}_${config.headers['Content-Type']}_${config.url}`
        if (reqQueue[key]) {
            reqQueue[key]()
        }
        let cancel
        config.cancelToken = new CancelToken(function executor(c) {
            // executor 函数接收一个 cancel 函数作为参数
            cancel = c
        })
        reqQueue[key] = cancel
    }
    return config
}

// 普通请求
const http = {
    get: (url, params = {}, extra) => {
        return axios({
            url: url,
            method: 'get',
            params: params,
            ...extra
        })
    },
    // 默认post采用json形式
    post: (url, params = {}, extra = {}) => {
        let conf = {
            headers: {
                'Content-Type': 'application/json'
            }
        }
        conf = Object.assign(conf, extra)
        return axios({
            url: url,
            data: params,
            method: 'post',
            ...conf
        })
    },
    // 表单形式post
    postForm: (url, params = {}, extra = {}) => {
        let conf = {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        }
        conf = Object.assign(conf, extra)
        return axios({
            url: url,
            data: params,
            method: 'post',
            ...conf
        })
    },
    put: (url, params = {}, extra = {}) => {
        let conf = {
            headers: {
                'Content-Type': 'application/json'
            }
        }
        conf = Object.assign(conf, extra)
        return axios({
            url: url,
            data: params,
            method: 'put',
            ...conf
        })
    },
    putForm: (url, params = {}, extra = {}) => {
        let conf = {
            headers: {
                'Content-Type': 'application/x-www-form-urlencoded'
            }
        }
        conf = Object.assign(conf, extra)
        return axios({
            url: url,
            data: params,
            method: 'put',
            ...conf
        })
    },
    delete: (url, params = {}, extra) => {
        return axios({
            url: url,
            method: 'delete',
            params: params,
            ...extra
        })
    },
    GetDownload: (url, params = {}, extra = {}) => {
        let conf = {
            responseType: 'blob'
        }
        conf = Object.assign(conf, extra)
        // 如果在内部处理了axios的结果，则需要套多一层promise，否则外部将得不到信息
        return new Promise((resolve, reject) => {
            axios({
                url: url,
                data: params,
                method: 'get',
                ...conf
            })
                .then((res) => {
                    const fileName = decodeURI(res.headers['content-disposition'].split(';')[1].split('=')[1])
                    let typeNum = fileName.lastIndexOf('.')

                    const type = fileName.substring(typeNum + 1)
                    const blob = new Blob([res.data])
                    const link = document.createElement('a')
                    link.download = fileName
                    link.style.display = 'none'
                    link.href = URL.createObjectURL(blob)
                    document.body.appendChild(link)
                    link.click()
                    URL.revokeObjectURL(link.href) // 释放URL 对象
                    document.body.removeChild(link)
                    resolve(true)
                })
                .catch((e) => {
                    reject(e.data)
                })
        })
    },
    upload: (url, params = {}, extra = {}) => {
        let conf = {
            headers: {
                'Content-Type': 'multipart/form-data'
            }
        }
        conf = Object.assign(conf, extra)
        return axios({
            url: url,
            data: params,
            method: 'post',
            ...conf
        })
    }
}

export default http
